package com.zryc.shop.ums.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.zryc.shop.ums.entity.Admin;
import com.zryc.shop.ums.entity.Role;
import com.zryc.shop.ums.service.IAdminLoginLogService;
import com.zryc.shop.ums.service.IAdminService;
import com.zryc.shop.ums.service.IMenuService;
import com.zryc.shop.ums.service.IRoleService;
import com.zryc.shop.util.JwtUtil;
import com.zryc.shop.util.ResponseResult;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.security.crypto.bcrypt.BCrypt;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.stereotype.Controller;
import springfox.documentation.annotations.ApiIgnore;

import javax.servlet.http.HttpSession;
import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;


/**
 * <p>
 * 后台用户表 前端控制器
 * </p>
 *
 * @author 王志平
 * @since 2024-10-01
 */
@RestController
@RequestMapping("/ums/admin")
@Api(tags = "管理员信息接口列表")
public class AdminController {

    private IAdminService adminService;
    private IRoleService roleService;

    @Autowired
    public AdminController(IAdminService adminService, IRoleService roleService) {
        this.adminService = adminService;
        this.roleService = roleService;
    }

    @PostMapping("/role/update")
    @ApiOperation("为管理员重新分配角色")
    public ResponseResult updateRole(@RequestParam @ApiParam(value = "管理员ID", required = true) Long adminId,
                                     @RequestParam @ApiParam(value = "角色ID列表", required = true, example = "1,2") String roleIds) {
        roleService.allocRole(adminId, roleIds);//给管理员重新分配角色
        return new ResponseResult(200, "执行成功");
    }

    @GetMapping("/role/{id}")
    @ApiOperation("查找某个管理员的角色列表")
    public ResponseResult getRole(@PathVariable @ApiParam(value = "管理员ID", required = true) Long id) {
        return new ResponseResult(200, "查询完成", roleService.getListByAdminId(id));
    }



    @PostMapping("/delete/{id}")
    @ApiOperation("删除管理员")
    public ResponseResult delete(@PathVariable @ApiParam(value = "管理员ID", required = true) Integer id) {
        adminService.removeById(id);
        return new ResponseResult(200, "删除成功");
    }

    @PostMapping(path = "/register", consumes = MediaType.APPLICATION_JSON_VALUE)
    @ApiOperation("注册（创建）管理员")
    public ResponseResult register(@RequestBody Admin admin) {
        admin.setPassword(BCrypt.hashpw(admin.getPassword(), BCrypt.gensalt()));
        admin.setCreateTime(LocalDateTime.now());
        adminService.save(admin);
        return new ResponseResult(200, "创建成功");
    }

    ///updateStatus/' + id
    @PostMapping("/updateStatus/{id}")
    @ApiOperation("更新管理员账号状态")
    public ResponseResult updateStatus(@PathVariable Integer id, @RequestParam Integer status) {
        UpdateWrapper<Admin> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("id", id);
        updateWrapper.set("status", status);
        adminService.update(updateWrapper);
        return new ResponseResult(200, "修改成功");
    }

    /**
     * 修改管理员信息的接口方法（可以修改除密码以外的其余信息）
     * @param id 管理员ID
     * @param admin 封装了除ID以外的管理员信息
     * @return
     */
    @PostMapping("/update/{id}")
    @ApiOperation("修改管理员信息")
    public ResponseResult update(@PathVariable @ApiParam(value = "管理员ID", required = true) Long id,
                                 @RequestBody Admin admin) {
        admin.setId(id);//设置ID
        admin.setPassword(null);//mybatis-plus进行update操作时会忽略掉为null的栏位
        adminService.updateById(admin);//用id做条件，修改其他栏位
        return new ResponseResult(200, "修改成功");
    }

    /**
     * 管理员账号更新自己的密码
     * GET /updatePassword/9?oldPass=123456&newPass=111111
     * POST /updatePassword/9
     * BODY oldPass=123456
     *      newPass=111111
     * @param id 管理员ID
     * @param oldPass 旧密码
     * @param newPass 新密码
     * @return
     */
    @PostMapping("/updatePassword/{id}")
    @ApiOperation("修改管理员密码")
    public ResponseResult updatePassword(@PathVariable @ApiParam(value = "管理员ID", required = true) Long id,
                                         @RequestParam @ApiParam(value = "旧密码", required = true) String oldPass,
                                         @RequestParam @ApiParam(value = "新密码", required = true) String newPass) {
        //1.先验证该账号旧密码是否正确
        Admin admin = adminService.getById(id);
        if (admin != null && BCrypt.checkpw(oldPass, admin.getPassword())) {
            //2.更新密码
            UpdateWrapper<Admin> updateWrapper = new UpdateWrapper<>();
            updateWrapper.eq("id", id);
            updateWrapper.set("password", BCrypt.hashpw(newPass, BCrypt.gensalt()));//将新密码加密后再更新
            adminService.update(updateWrapper);
            return new ResponseResult(200, "修改成功");
        }
        else {
            return new ResponseResult(401, "旧密码校验错误，无法更新");
        }
    }

    @GetMapping("/list")
    @ApiOperation("分页查询管理员列表")
    public ResponseResult list(@RequestParam(required = false) @ApiParam(value = "姓名或账号") String keyword,
                               @RequestParam(defaultValue = "1") @ApiParam(value = "页号", required = true) Integer pageNum,
                               @RequestParam(defaultValue = "10") @ApiParam(value = "页的大小", required = true) Integer pageSize) {
        QueryWrapper<Admin> queryWrapper = new QueryWrapper<>();
        if (!StringUtils.isEmpty(keyword)) {//如果关键字不为空着设置条件
            queryWrapper.eq("username", keyword)
                    .or()
                    .eq("nick_name", keyword);
        }
        Page<Admin> page = new Page<>(pageNum, pageSize);//补充分页信息
        adminService.page(page, queryWrapper);//调用分页查询的函数
        return new ResponseResult(200, "查询完成", page);
    }

    @PostMapping("/logout")
    @ApiOperation("管理员登出账号")
    public ResponseResult logout(@ApiIgnore HttpSession session) {
        session.invalidate();//将当前会话清空
        return new ResponseResult(200, "登出成功");
    }

    @PostMapping("/login")
    @ApiOperation("管理员登录账号")
    public ResponseResult login(@RequestBody Admin admin) {
        Admin user = adminService.login(admin.getUsername(), admin.getPassword());//完成登录验证
        if (user == null) {//用户名或密码错误
            return new ResponseResult(401, "登录失败，用户名或密码错误");
        }
        else {//登录成功，生成jwt并返回
            Map<String, String> data = new HashMap<>();
            data.put("tokenHead", "Bearer ");
            // 3个小时 * 60分钟 * 60秒 * 1000毫秒 = 令牌的有效时间为3小时
            data.put("token", JwtUtil.create(3 * 60 * 60 * 1000, user.getId().toString(), user.getUsername()));
            return new ResponseResult(200, "登陆成功", data);
        }
    }

    @GetMapping("/info")
    @ApiOperation("获取当前管理员信息")
    public ResponseResult info(@RequestHeader("Authorization") @ApiParam(value = "登录令牌", required = true) String token) {
        String userinfo = JwtUtil.parse(token.split(" ")[1]);//return claims.get("userId", String.class) + "," + claims.get("username", String.class);
        Admin admin = adminService.getById(userinfo.split(",")[0]);
        //注入管理员的权限信息
        adminService.permissionInfo(admin);
        return new ResponseResult(200, "查询完成", admin);
    }

    @GetMapping("/briefInfo")
    @ApiOperation("获取当前管理员简略信息")
    public ResponseResult briefInfo(@RequestHeader("Authorization") @ApiParam(value = "登录令牌", required = true) String token) {
        String userinfo = JwtUtil.parse(token.split(" ")[1]);//return claims.get("userId", String.class) + "," + claims.get("username", String.class);
        Admin admin = adminService.getById(userinfo.split(",")[0]);
        //注入管理员的权限信息
//        adminService.permissionInfo(admin);
        return new ResponseResult(200, "查询完成", admin);
    }

}
